home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
DELPHI32
/
DEBUG
/
STAKWK10
/
STAKWALK.TXT
< prev
next >
Wrap
Text File
|
1996-05-19
|
8KB
|
162 lines
StackWalker 1.0: Delphi 2.0 debugger helper.
Copyright (c) 1996, D.J. Murdoch
These units (STAKWALK and STAKLOW) help with the problem of exceptions
occurring in the run-time library in Borland's Delphi 2.0: the
debugger often can't find where in your code the error was triggered.
The problem is that when an exception occurs, the debugger tries to
walk up the stack until it finds a return address in your source code.
However, sometimes it can't walk up the stack, and so it can't find
the error. (This might be related to whether you have stack frames
turned on, but sometimes doing that is not enough.)
What I did to fix this in StackWalker was to install an exception
handler that would look at *every* value on the stack, trying to find
one that appears to be a return address to code with source. It does
this by reading the .MAP file to figure out source addresses, and then
just comparing everything on the stack to those until it turns
something up.
This procedure is definitely not bulletproof. There are lots of
reasons to have addresses on the stack that aren't return addresses;
if you do, StackWalker will give false messages. However, getting a
few false addresses mixed in with the real ones is better than getting no
information at all.
To use it:
1. Set the detailed map file linker option on. This is in the
Project|Options|Linker page. StackWalker uses the .MAP file to
figure out what return addresses correspond to code. If it can't
find the .MAP file in the same directory as the executable, or
can't find the line number records in the .MAP file, it gives a
warning and makes wild guesses, which give so many false alarms
that it'll soon convince you to generate the .MAP file.
2. Set the $D+ option on for every unit where you want to see the
errors. StackWalker won't show addresses in units compiled $D-
(unless you forgot to make the .MAP file).
3. Link one of the StackWalker units into your code. There are 2 ways
to do this:
a) If you've got a regular Delphi application, then add
StakWalk to the project. It will automatically install all the
hooks to get things working.
OR b) In a console mode application or other application that doesn't
use VCL, add StakLow to the project or to a Uses clause
somewhere. It will install itself as the default exception
handler. (This doesn't work in a VCL application, because the
default handler never gets called.) You won't get the helpful
dialog that StakWalk gives you, but it should still give you the
same information.
If you have your own default exception handler, you might find
that StakLow messes it up, or doesn't get activated. But if
you've got your own exception handler, you're probably clever
enough to figure out how to fix this kind of problem.
4. Compile and run your program and do whatever it is that triggers
the exception. After the usual unhelpful message pops up telling
you that an exception happened somewhere (but not telling you
where), hit F9 to continue running. At this point StackWalker will
examine the stack and trigger an exception at every place it thinks
might be in the call stack. (You'll likely get a few false alarms.
If there was a foolproof way to do this, Delphi would do it
itself).
5. When you've found the place that really caused the trouble, click
Cancel in the StackWalker dialog (or manually change the value of
the global variable StopWalker to True) to stop it from walking
all the way back up the stack. If you don't do this and let it go
too far, it'll eventually trigger an exception at the
"Application.Run" line. If you keep going past that, you may find
weird behaviour (e.g. I found once that StackWalker got turned off
for no apparent reason); I think by that point your program may be
messed up, so be careful.
You can have a little more control over the behaviour by manually
setting some of the global variables in the StakLow unit:
WalkerActive: set this to False when you don't need the
special handling for future exceptions.
StopWalker: set this to True to stop the current walk.
ContinueFunc: assign a boolean function to this variable, to
replace StakWalk's dialog. It will be called just before the
exception is triggered, and should return true if you want
another debug exception generated.
You can also make a call to WalkStack at any time to trigger a walk
through the stack.
BUGS:
For reasons I don't understand and don't know how to fix, floating
point exceptions sometimes mess up StackWalker. You'll just get the
regular exception message over and over again, and never find out
where it was triggered. If you know how to fix this, please tell me.
FILES:
This package contains the following files:
STAKWALK.TXT: This doc file.
STAKWALK.PAS: The high level unit to use to turn on StackWalker.
STAKWALK.DFM: The form file for the StackWalker dialog.
STAKLOW.PAS: The low level unit used by STAKWALK, or directly if
you don't use VCL.
PROJECT1.DPR, UNIT1.PAS, UNIT1.DFM: A simple demonstration project.
RELEASE HISTORY:
Version 0.1: Initial release
0.2: Forced optimization off in StakLow, so test for stack
doesn't get optimized away
0.3: Added check for debugger, so you can distribute code to
testers but not have the dialog pop up except when they're
debugging.
1.0: First public release; same as 0.3.
LICENSE:
StackWalker is not public domain code. Its copyright belongs to
Duncan Murdoch. You are licensed to use it at no charge, but may not
sell it or incorporate it into another product without prior written
permission. You may not charge more than $1 for the distribution of
StackWalker. You may include it in a CDROM compilation provided you
charge no more than $1 per package in the compilation. As a courtesy,
I would appreciate receiving a copy of any CDROM that includes it, but
this is not a legal requirement.
I do not offer any guarantee or support for StackWalker. It works at
a low level, and there may well be conditions that cause it to crash
your program, Delphi, or Windows.
If StackWalker helps you so much that you want to show your
appreciation in a monetary way, you may send a contribution in any
amount to
D.J. Murdoch
337 Willingdon Ave.
Kingston, Ontario, Canada
K7L 4J3
For contributions of $20 (US or Canadian) or more, I'll send you a
diskette containing the latest version of StackWalker and a collection
of other utilities that I've written. Please make payments by US
dollar cheque drawn on a US bank, Canadian dollar cheque drawn on a
Canadian bank, or pounds Stirling cheque drawn on a UK bank
(equivalent to $20 US, if you want the diskette). Unfortunately, I
can't accept credit cards to handle payments from people from other
countries. However, I do have an arrangement with the Public Software
Library to accept shareware registrations for various programs by
credit card, and some of those will get you the disk; write to me for
details.
Duncan Murdoch
dmurdoch@mast.queensu.ca